home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
GL
/
newton
/
models.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
11KB
|
503 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* Newton model building routines
* HISTORICAL NOTE: a Newton model used to be called a ``jello'', hence
* some of the `j's that appear throughout the code ...
* Yossi Friedman, July 1988
*/
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <gl.h>
#include "config.h"
#include "newton.h"
extern char *cwd();
static char *model_fnames[MAX_MODELS], **end_model_fnames;
#define LINELEN 10240
static Atom *new_atom(float, float, float);
static Spring *new_spring(float, Atom *, Atom *);
static Surf *new_surf(int, Atom **);
initialize_models()
{
FILE *fp;
char line[LINELEN];
char *p, *q, *r;
int len;
int n;
/*
* grab the list of names from model catalog
*/
if (strcmp(model_catalog, "-") == 0)
fp = stdin;
else {
fp = fopen(model_catalog, "r");
if (fp == NULL) {
fprintf(stderr, "newton: Could not open %s/%s\n", cwd(),
model_catalog);
my_exit(1);
}
}
end_model_names = model_names;
end_model_fnames = model_fnames;
n = 0;
while(fgets(line, LINELEN, fp) != NULL) {
for (p = line; *p && (*p != '\n') && (*p != '#');) {
/* skip white space */
if (isspace(*p)) {
p++;
continue;
}
/* make sure we have space */
if (++n >= MAX_MODELS) {
fprintf(stderr, "newton: too many models in the catalog. Max is %d\n", MAX_MODELS);
my_exit(1);
}
/* found a beginning of a name. Figure out where it ends */
for (q = p+1; *q && (*q != '\n') && (*q != '#'); q++)
if (isspace(*q))
break;
len = q - p;
p[len] = 0;
*end_model_fnames = (char *) malloc(1 + len);
if (*end_model_fnames == NULL) {
fprintf(stderr, "newton: Could not malloc\n");
my_exit(1);
}
strcpy(*end_model_fnames++, p);
if (p[len-1] == 'j' && p[len-2] == '.')
p[len-2] = '\0';
if ((r = strrchr(p, '/')) != NULL)
p = r + 1;
len = strlen(p);
*end_model_names = (char *) malloc(1 + len);
if (*end_model_names == NULL) {
fprintf(stderr, "newton: Could not malloc\n");
my_exit(1);
}
strcpy(*end_model_names++, p);
/* advance to the next name */
p = q+1;
}
}
if (end_model_names - model_names == 0) {
fprintf(stderr, "newton: No model description files\n");
my_exit(1);
}
/* by default, build the first model on the list */
model_index = 0;
build_model(1);
}
build_model(int from_scratch)
{
char *model_fname;
FILE *fp;
char line[LINELEN];
char *p;
int q;
int from, to, v, n;
float old_max_k, x, y, z, k, f;
Atom *surf_buf[MAX_SURF_N];
free_atoms();
free_springs();
free_surfs();
model_fname = model_fnames[model_index];
fp = fopen(model_fname, "r");
if (fp == NULL) {
fprintf(stderr, "newton: Could not open ");
if (model_fname[0] != '/')
fprintf(stderr, "%s/", cwd());
fprintf(stderr, "%s\n", model_fname);
my_exit(1);
}
if (from_scratch) {
/* set the default material properites for the model */
model_material_size = default_model_material_size;
memcpy(model_material, default_model_material,
model_material_size * sizeof(float));
/* set the default draw functions for the model */
draw_model = DRAW_MODEL_DEFAULT;
springs_too = SPRINGS_TOO_DEFAULT;
alpha_blended = ALPHA_BLENDED_DEFAULT;
}
old_max_k = max_k;
max_k = -1500.; /* minus infinity */
while (fgets(line, LINELEN, fp) != NULL)
switch (line[0]) {
case '\n':
case '#':
continue;
case 'a':
sscanf(line + 1, "%f %f %f", &x, &y, &z);
new_atom(x, y, z);
break;
case 'c':
sscanf(line + 1, "%f %d %d", &k, &from, &to);
(void) new_spring(k, &model_atoms[from], &model_atoms[to]);
if (max_k < k)
max_k = k;
break;
case 's':
p = line + 1;
for (n = 0; sscanf(p, "%d%n", &v, &q) == 1; p += q) {
if (n == MAX_SURF_N) {
fprintf(stderr, "newton: %s: Surface too big\n", model_fname);
my_exit(1);
}
surf_buf[n++] = &model_atoms[v];
}
(void) new_surf(n, surf_buf);
break;
case 'M':
p = line + 1;
for (n = 0; sscanf(p, "%f%n", &f, &q) == 1; p += q) {
if (n == MAX_LIGHTING_SIZE) {
fprintf(stderr, "newton: %s: Material too big\n", model_fname);
my_exit(1);
}
model_material[n++] = f;
}
model_material_size = n;
break;
case 'S':
draw_model = draw_smooth_surfs;
break;
case 'F':
draw_model = draw_flat_surfs;
break;
case 'B':
if (from_scratch && (mode != COLOR_MAP)) {
mode = COLOR_MAP;
cmode();
gconfig();
}
break;
default:
fprintf(stderr, "newton: %s: Syntax error\n", model_fname);
my_exit(1);
}
fclose(fp);
#ifdef MP
{
/*
* divide the atoms, springs and surfs lists
*/
int i;
int n_atoms = (end_model_atoms TOTAL - model_atoms) / nproc;
int n_springs = (end_model_springs TOTAL - model_springs) / nproc;
int n_surfs = (end_model_surfs TOTAL - model_surfs) / nproc;
end_model_atoms MASTER = model_atoms + n_atoms;
end_model_springs MASTER = model_springs + n_springs;
end_model_surfs MASTER = model_surfs + n_surfs;
for (i = 1; i < nproc - 1; i++) {
end_model_atoms[i] = end_model_atoms[i-1] + n_atoms;
end_model_springs[i] = end_model_springs[i-1] + n_springs;
end_model_surfs[i] = end_model_surfs[i-1] + n_surfs;
}
}
#endif /* MP */
/*
* this is necessary in order to set dt and redraw the K slider
*/
if (from_scratch)
#if ECLIPSE || CLOVER1 /* the slow machines */
set_default_k(max_k / 2.0);
#else /* ECLIPSE || CLOVER1 */
set_default_k(max_k);
#endif /* ECLIPSE || CLOVER1 */
else
set_k(old_max_k);
/*
* set the model material
*/
if (from_scratch) {
#ifndef HAS_BLENDING
/* kludge to avoid crashes due to alpha blending */
if (model_material[0] == (float)ALPHA)
lmdef(DEFMATERIAL,
MODEL_MATERIAL_INDEX,
model_material_size - 2,
model_material + 2);
else
#endif /* HAS_BLENDING */
lmdef(DEFMATERIAL,
MODEL_MATERIAL_INDEX,
model_material_size,
model_material);
}
}
/*
* rotate the model in the ROOM coordinate system
* around a VIEWING axis
*/
rotate_model(Angle alpha, char axis)
{
/*
* the formula is:
* v R = v M rot M_inv,
* where rot is the rotation matrix (in the viewing system) around the
* viewing axis.
*/
pushmatrix();
loadmatrix(M_inv);
rotate(alpha, axis);
multmatrix(M);
getmatrix(R);
popmatrix();
SLAVE_FUNC(DO_ROTATE_MODEL);
do_rotate_model(model_atoms, end_model_atoms MASTER);
WAIT_FOR_SLAVE();
}
do_rotate_model(Atom *start, Atom *finish)
{
Atom *ap;
float ov[3], *v;
for (ap = start; ap < finish; ap++) {
v = ap->pos;
ov[X] = v[X]; ov[Y] = v[Y]; ov[Z] = v[Z];
apply(v, ov, R);
}
}
/*
* Data Structure Stuff
*/
free_atoms()
{
#ifdef MP
{
int i;
for (i = 0; i < nproc; i++)
end_model_atoms[i] = model_atoms;
}
#else /* MP */
end_model_atoms = model_atoms;
#endif /* MP */
}
static Atom *
new_atom(float x, float y, float z)
{
if (end_model_atoms TOTAL == model_atoms + MAX_ATOMS) {
fprintf(stderr, "newton: %s: Too many atoms\n", model_names[model_index]);
my_exit(1);
}
end_model_atoms TOTAL ->pos[X] = x;
end_model_atoms TOTAL ->pos[Y] = y;
end_model_atoms TOTAL ->pos[Z] = z;
end_model_atoms TOTAL ->vel[X] = 0.0;
end_model_atoms TOTAL ->vel[Y] = 0.0;
end_model_atoms TOTAL ->vel[Z] = 0.0;
#ifdef MP
{
int i;
for (i = 0; i < nproc; i++)
end_model_atoms TOTAL ->acc[i][X] =
end_model_atoms TOTAL ->acc[i][Y] =
end_model_atoms TOTAL ->acc[i][Z] = 0.;
}
#else /* MP */
end_model_atoms TOTAL ->acc[X] =
end_model_atoms TOTAL ->acc[Y] =
end_model_atoms TOTAL ->acc[Z] = 0.0;
#endif /* MP */
return(end_model_atoms TOTAL ++);
}
free_springs()
{
#ifdef MP
{
int i;
for (i = 0; i < nproc; i++)
end_model_springs[i] = model_springs;
}
#else /* MP */
end_model_springs = model_springs;
#endif /* MP */
}
static Spring *
new_spring(float k, Atom *a1, Atom *a2)
{
float r0[3];
if (end_model_springs TOTAL == model_springs + MAX_SPRING) {
fprintf(stderr, "newton: %s: Too many springs\n", model_names[model_index]);
my_exit(1);
}
end_model_springs TOTAL ->k = k;
end_model_springs TOTAL ->from = a1;
end_model_springs TOTAL ->to = a2;
vec_op(r0, a1->pos, -, a2->pos);
end_model_springs TOTAL ->r0 = sqrt(r0[X]*r0[X] + r0[Y]*r0[Y] + r0[Z]*r0[Z]);
return(end_model_springs TOTAL ++);
}
free_surfs()
{
Surf *sp;
for (sp = model_surfs; sp < end_model_surfs TOTAL; sp++) {
free(sp->vert);
free(sp->norm);
}
#ifdef MP
{
int i;
for (i = 0; i < nproc; i++)
end_model_surfs[i] = model_surfs;
}
#else /* MP */
end_model_surfs = model_surfs;
#endif /* MP */
}
static Surf *
new_surf(int n, Atom **vert)
{
Atom **ap;
if (end_model_surfs TOTAL == model_surfs + MAX_SURF) {
fprintf(stderr, "newton: %s: Too many surfs\n", model_names[model_index]);
my_exit(1);
}
if (n < 3) {
fprintf(stderr, "newton: %s: Surf too small\n", model_names[model_index]);
my_exit(1);
}
end_model_surfs TOTAL ->n = n;
end_model_surfs TOTAL ->vert = (Atom **) malloc(n * sizeof(Atom *));
if (end_model_surfs TOTAL ->vert == NULL) {
fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
my_exit(1);
}
for (ap = end_model_surfs TOTAL ->vert; n--; *ap++ = *vert++)
;
end_model_surfs TOTAL ->norm = (float *) malloc(end_model_surfs TOTAL ->n * 4 * sizeof(float));
if (end_model_surfs TOTAL ->norm == NULL) {
fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
my_exit(1);
}
return(end_model_surfs TOTAL ++);
}